<?php
/**
 * Created by PhpStorm.
 * User: Administrator【wenruns】
 * Date: 2021/1/26
 * Time: 9:33
 */

namespace WenRuns\Laravel\Admin\Form\Field\MultiList;

use Encore\Admin\Facades\Admin;

/**
 * Class TableList
 * @package App\Admin\Extensions\Form\MultiList
 */
class TableList
{
    use CommonMethods;

    protected $style = '';

    /**
     * @var MultiList|null
     */
    public $multiList = null;

    /**
     * @var array
     */
    protected $columns = [];

    /**
     * @var null
     */
    public $parentColumn = null;

    /**
     * @var array
     */
    protected $defaultValues = [];

    /**
     * @var string
     */
    protected $content = '';

    /**
     * @var string
     */
    protected $unique = '';

    /**
     * @var null
     */
    protected $value = null;

    /**
     * @var int
     */
    protected $key = 0;

    /**
     * @var string
     */
    public $buttonEventClosure = null;

    /**
     * @var bool
     */
    protected $showButton = false;

    /**
     * @var string
     */
    public static $scripts = [];

    /**
     * @var bool
     */
    public $enableInsertEleAfterActive = false;

    protected $oneRowScript = '';

    public $children = [];

    /**
     * @var bool
     */
    protected $subTableList = false;

    /**
     * TableList constructor.
     * @param MultiList $multiList
     * @param null $parentColumn
     */
    public function __construct(MultiList $multiList, $parentColumn = null)
    {
        $this->multiList = $multiList;
        $this->parentColumn = empty($parentColumn) ? $multiList->column() : $parentColumn;
    }

    /**
     * @param bool $bool
     * @return $this
     */
    public function setSubTableList($bool = true)
    {
        $this->subTableList = $bool;
        return $this;
    }

    /**
     * @return int|string
     */
    public function getUniqueKey()
    {
        if (empty($this->unique)) {
            $this->unique = mt_rand(10000, 99999);
        }
        return $this->unique;
    }

    /**
     * @param $value
     * @param int $key
     * @return $this
     */
    public function value($value, $key = 0)
    {
        $this->value = $value;
        $this->key = $key;
        return $this;
    }

    /**
     * @return int
     */
    public function getColumnLen()
    {
        return count($this->columns) + ($this->showButton ? 1 : 0);
    }

    /**
     * @param $value
     * @return $this
     */
    public function default($value)
    {
        $this->defaultValues = $value;
        return $this;
    }

//    /**
//     * @return string
//     */
//    public function render()
//    {
//        dd(11);
//        $this->content = $this->tableListHead() . $this->tbodyStart();
//        if (!empty($this->defaultValues)) {
//            if (count($this->defaultValues) == count($this->defaultValues, true)) {
//                $this->content .= $this->value($this->defaultValues)->tableListBody();
//            } else {
//                foreach ($this->defaultValues as $k => $item) {
//                    $this->content .= $this->value($item, $k)->tableListBody();
//                }
//            }
//        }
//        $this->content .= $this->tableListEnd();
//        return $this->content;
//    }


    /**
     * @return string
     */
    public function tableListHead()
    {
        $content = $this->tableStart() . $this->theadStart() . $this->trStart();
        foreach ($this->columns as $key => $column) {
            if ($column->type == 'hidden') {
                continue;
            }
            $content .= $this->thStart($column) . $column->render() . $this->thEnd();
        }
        $content .= $this->addButton();
        $content .= $this->trEnd() . $this->theadEnd();

        return $content;
    }

    /**
     * @return string
     */
    protected function addButton()
    {
        if (!$this->showButton) {
            return '';
        }
        AddEvent::add($this);
        $number = count($this->multiList->getOptions());
        return <<<HTML
<th>
    <span class="table-list-btn-add-{$this->getUniqueKey()} add-row-btn" data-type="add" data-number="{$number}" style="padding: 5px;cursor: pointer;">
        <i class="fa fa-plus-square" style="color: green"></i>
    </span>
</th>
HTML;
    }


    /**
     * @return string
     */
    protected function removeButton()
    {
        if (!$this->showButton) {
            return '';
        }
        RemoveEvent::remove($this);
        return <<<HTML
<td>
    <span class="table-list-btn-remove-{$this->getUniqueKey()} remove-row-btn" data-type="remove" style="padding: 5px;cursor: pointer;">
        <i class="fa fa-trash" style="color: red"></i>
    </span>
</td>
HTML;
    }

    /**
     * @param $jsEventClosure
     * @return $this
     */
    public function showButton($jsEventClosure)
    {
        $this->showButton = true;
        if (is_callable($jsEventClosure)) {
            $this->buttonEventClosure = $this->compressHtml(call_user_func($jsEventClosure));
            return $this;
        }
        $this->buttonEventClosure = $this->compressHtml($jsEventClosure);
        return $this;
    }

    /**
     * @param bool $enable
     * @return $this
     */
    public function enableInsertEleAfterActive($enable = true)
    {
        $this->enableInsertEleAfterActive = $enable;
        return $this;
    }

    /**
     * @return int|string
     */
    public function getKeyVariableName()
    {
        return $this->getUniqueKey();
    }


    /**
     * @return string
     */
    public function tableListBody($key = 0)
    {
        if (empty($this->value) && empty($this->createEmpty)) {
            return '';
        }
        $expandOrModal = '';
        $bodyContent = $this->trStart($key);
        $scriptIndex = $this->getTableKey() . ($this->createEmpty ? '_oneRow' : '');
        $script = self::$scripts[$scriptIndex] ?? '';
        $noScript = empty($script);
        foreach ($this->columns as $key => $column) {
            $field = $column->createEmpty($this->createEmpty)
                ->keyIsVariable($this->keyIsVariable, $this->getKeyVariableName())
                ->renderValue($this->value, $this->key);
            if ($column->type == 'hidden') {
                $bodyContent .= $field->render();
                continue;
            }
            $bodyContent .= $this->tdStart($field) . $field->render() . $this->tdEnd();
            $expandOrModal .= $field->renderSub();
            if ($noScript) {
                if ($this->createEmpty) {
                    $script .= $field->getOneRowScript();
                } else {
                    $script .= $field->getScript();
                }
            }
        }
        if ($this->createEmpty) {
            $this->oneRowScript = $script;
        }
        self::$scripts[$scriptIndex] = $script;
        if ($noScript && !$this->createEmpty) {
            Admin::script($script);
        }
        $bodyContent .= $this->removeButton() . $this->trEnd() . $expandOrModal;
        return $bodyContent;
    }

    /**
     * @return string
     */
    public function getOneRowHtml()
    {
        $this->createEmpty = true;
        $content = $this->createEmpty(true)->keyIsVariable(true)->tableListBody();
        return $content;
    }

    /**
     * @return mixed
     */
    public function getOneScript()
    {
        return $this->oneRowScript;
    }


    /**
     * @return string
     */
    public function tableListEnd()
    {
        return $this->tbodyEnd() . $this->tableEnd();
    }

    /**
     * @param int $key
     * @return string
     */
    public function trStart($key = 0)
    {
        if ($this->createEmpty) {
            $key = MultiList::SYMBOL_BEGIN . $this->getUniqueKey() . MultiList::SYMBOL_END;
            AddEvent::addReplaceString($key);
        }
        return '<tr
        data-col="' . $key . '"
        data-begin="' . MultiList::SYMBOL_BEGIN . '"
        data-end="' . MultiList::SYMBOL_END . '"
        data-key="' . $this->getUniqueKey() . '"
        class="' . $this->getTableKey() . '-tr">';
    }

    /**
     * @return string
     */
    public function trEnd()
    {
        return '</tr>';
    }

    /**
     * @param bool $empty
     * @return string
     */
    public function tbodyStart($empty = false)
    {
        if ($empty) {
            return '<tbody data-empty="true">';
        }
        return '<tbody>';
    }

    /**
     * @return string
     */
    public function tbodyEnd()
    {
        return '</tbody>';
    }

    /**
     * @return string
     */
    public function theadStart()
    {
        return '<thead>';
    }

    /**
     * @return string
     */
    public function theadEnd()
    {
        return '</thead>';
    }

    public function getTableKey()
    {
        return 'grid-table-' . $this->multiList->getUniqueKey(); // .$this->getUniqueKey()
    }

    /**
     * @return string
     */
    public function tableStart()
    {
        return '<table
            class="table table-hover"
            id="' . $this->getTableKey() . '"
            data-sub="' . ($this->subTableList ? 'true' : 'false') . '">';
    }

    /**
     * @return string
     */
    public function tableEnd()
    {
        return '</table>';
    }

    /**
     * @param BaseColumn $column
     * @return string
     */
    public function thStart(BaseColumn $column)
    {
        return '<th style="width:' . $column->width . '" class="">';
    }

    /**
     * @return string
     */
    public function thEnd()
    {
        return '</th>';
    }


    /**
     * @param Field $field
     * @return string
     */
    public function tdStart(Field $field)
    {
        return '<td class="' . $field->getClass() . '" style="' . $this->checkStyle($this->getStyle()) . '">';
    }

    /**
     * @return string
     */
    public function tdEnd()
    {
        return '</td>';
    }


    /**
     * @return mixed
     */
    public function getStyle()
    {
        return $this->style;
    }

    protected function checkStyle($style)
    {
        if (is_array($style)) {
            $str = '';
            foreach ($style as $key => $item) {
                $str .= $key . ':' . $item . ';';
            }
            return $str;
        }
        return $style;
    }

    /**
     * @param $style
     * @return $this
     */
    public function style($style)
    {
        $this->style = $style;
        return $this;
    }

    public function __get($name)
    {
        // TODO: Implement __get() method.
        return $this->$name;
    }

}
